`timescale 1ns / 1ps

module pwc2_fish #(
    parameter N_INH     = 1,
    parameter N_INW     = 16,
    parameter N_OUT     = 16,
    parameter N_ICH     = 384,
    parameter N_OCH     = 512,
    parameter BIT_I     = 8,
    parameter BIT_W     = 5,
    parameter BIT_O     = 16,
    parameter ROM_FILE  = "L9_PW.mem",
    parameter ROM_TYPE  = "block",
    parameter ROM_LATENCY = 2,
    parameter RAM_TYPE  = "distributed",
    parameter RAM_LATENCY = 1
)
(
    input   clk,
    input   rst,
    
    input   i_vld,
    output  i_rdy,
    input   [N_INW*BIT_I-1 : 0]    i_data,
    
    output  o_vld,
    input   o_rdy,
    output  [BIT_O-1 : 0]    o_data
);

wire a_rdy, a_vld;
wire [N_INH*N_OUT*BIT_O-1 : 0] a_data;

wire b_rdy, b_vld;
wire [BIT_O-1 : 0] b_data;

pwc2 #(
    .N_INH       ( N_INH        ),
    .N_INW       ( N_INW        ),
    .N_OUT       ( N_OUT        ),
    .N_ICH       ( N_ICH        ),
    .N_OCH       ( N_OCH        ),
    .BIT_I       ( BIT_I        ),
    .BIT_W       ( BIT_W        ),
    .BIT_O       ( BIT_O        ),
    .ROM_TYPE    ( ROM_TYPE     ),
    .ROM_FILE    ( ROM_FILE     ),
    .ROM_LATENCY ( ROM_LATENCY  ),
    .RAM_TYPE    ( RAM_TYPE     ),
    .RAM_LATENCY ( RAM_LATENCY  )
) inst_pwc2
(
    .clk        (clk),
    .rst        (rst),
    .i_vld      (i_vld),
    .i_rdy      (i_rdy),
    .i_data     (i_data),
    .o_vld      (a_vld),
    .o_rdy      (a_rdy),
    .o_data     (a_data)
);

reduceWidth #(
    .N     (N_INH * N_OUT),
    .WIDTH (BIT_O)
)
inst_reduce (
    .clk                     ( clk      ),
    .rst                     ( rst      ),

    .i_rdy                   ( a_rdy    ),
    .i_vld                   ( a_vld    ),
    .i_data                  ( a_data   ),

    .o_rdy                   ( b_rdy    ),
    .o_vld                   ( b_vld    ),
    .o_data                  ( b_data   )
);

pwc2_reorder #(
    .N_HI        ( N_INH   ),
    .N_IO        ( 1       ),
    .N_BK        ( N_INW   ),
    .N_CH        ( N_OCH   ),
    .BIT         ( BIT_O   ),
    .RAM_LATENCY ( 2       )
)
inst_reorder (
    .clk                     ( clk      ),
    .rst                     ( rst      ),

    .i_rdy                   ( b_rdy    ),
    .i_vld                   ( b_vld    ),
    .i_data                  ( b_data   ),

    .o_rdy                   ( o_rdy    ),
    .o_vld                   ( o_vld    ),
    .o_data                  ( o_data   )
);

endmodule

